import React, { Component } from 'react';
import Taro, { Config } from '@tarojs/taro';
import { View, ScrollView } from '@tarojs/components'
import classnames from 'classnames'
import { connect } from 'react-redux'
import { debounce } from '@/utils'
import { getCityList, switchCity } from '@/store/location/action'
import { openCities } from '@/api'
import './index.scss'

interface State{
    cityList: {
      chars: string
      list: {
        id: string
        name: string
      }[]
    }[] | null
    scrollId: string
    cityDom: any
    charsDom: any
    charsTips: boolean
    scrollTop: number
    charsListDom: any
    openList: {
      name: string
      zipcode: string
    }[] | null
}

@connect<any>(
  ({ location }) => ({ location }),
  _dispatch => ({
    dispatchCity() {
      return _dispatch(getCityList())
    },
    dispatchSWcity(city) {
      return _dispatch(switchCity(city))
    }
  })
)
export default class Index extends Component<any> {
  constructor() {
    super(...arguments);
    this.state = {
      cityList: null,// 城市列表
      scrollId: '',
      cityDom: [],
      charsDom: [],
      charsTips: false,
      scrollTop: 0,
      charsListDom: null,
      openList: null,//已开通城市服务
    }
  }
  state: State
  UNSAFE_componentWillMount() {}
  async componentDidMount() {
    openCities().then(res => {
      const data = res.data.data
      this.setState({
        openList: data
      })
    })
    const { dispatchCity } = this.props
    const cityList = await dispatchCity()
    this.setState(
      {
        cityList
      },
      () => {
        this.cityListDomInfo()
      }
    )
  }
  UNSAFE_componentWillReceiveProps(nextProps, nextContext) {}
  componentWillUnmount() {}
  componentDidShow() {}
  componentDidHide() {}
  componentDidCatchError() {}
  componentDidNotFound() {}

  cityListDomInfo() {
    const query = Taro.createSelectorQuery()
    query
      .selectAll('.city-list-group')
      .boundingClientRect(e => {
        this.setState({
          cityDom: e
        })
      })
      .selectAll('.chars-list .str')
      .boundingClientRect((e: any) => {
        const charsListDom = {
          offsetTop: e[0].top,
          height: e[0].height * e.length,
          childHeight: e[0].height
        }
        this.setState({
          charsDom: e,
          charsListDom
        })
      })
      .exec()
  }

  scrollCity = debounce(e => {
    const { cityDom, scrollId, charsTips } = this.state
    const { scrollTop } = e.detail
    if (charsTips) return
    for (let i = cityDom.length; i; i--) {
      const dom = cityDom[i - 1]
      if (scrollTop >= dom.top) {
        if (scrollId === dom.id) break
        this.setState({
          scrollId: dom.id
        })
        break
      }
    }
  }, 50)

  changeCharsStatus(e, mode = 'tapStart') {
    const { charsListDom } = this.state
    const diff = e.touches[0].clientY - charsListDom.offsetTop
    const nextPlay = diff >= 0 && diff <= charsListDom.height
    if (!nextPlay) return
    const { charsDom, cityDom } = this.state
    const index = Math.floor((diff / charsListDom.childHeight))
    const dom = charsDom[index]

    if (mode !== 'tapStart') {
      const { scrollId } = this.state
      if (scrollId === dom.id) return
    }

    this.setState(
      {
        scrollTop: cityDom[index].top,
        scrollId: dom.id,
        charsTips: true
      },
      () => Taro.vibrateShort()
    )
  }

  tapCharsStart(e) {
    this.changeCharsStatus(e)
  }

  tapCharsMove = e => {
    this.changeCharsStatus(e, 'tapMove')
  }

  tapCharsEnd() {
    this.setState({
      charsTips: false
    })
  }

  setCity(cityName) {
    const { dispatchSWcity } = this.props
    dispatchSWcity(cityName)
    Taro.navigateBack()
  }

   isOpen(name) {
    const propsLocation = this.props.location
    if (propsLocation) {
      let cityName = propsLocation.cityName || (propsLocation.address && propsLocation.address.city)
      if (cityName) {
        return name.indexOf(cityName) !== -1
      } else {{
        return false
      }}
    }
    return false
  }

  render() {
    const { cityList, scrollId, charsTips, scrollTop, openList } = this.state

    return (
      cityList && (
        <View className='city-main'>
          <ScrollView
            className='city-wrap'
            onScroll={e => this.scrollCity(e)}
            scroll-y
            scrollTop={scrollTop}
          >
            {
              openList && (
                <View className='open-city'>
                  <View className='strong'>已开通服务的城市</View>
                  <View className='open-city-items'>
                    {
                      openList.map(v => {
                        return <View key={v.zipcode} onClick={() => this.setCity(v.name)} className={classnames('open-city-list', this.isOpen(v.name) && 'curr')}>{v.name}</View>
                      })
                    }
                  </View>
                  <View className='strong'>看看其他城市周边是否有门店</View>
                </View>
              )
            }
            {cityList.map(v => {
              return (
                <View
                  key={v.chars}
                  id={`city-${v.chars}`}
                  className='city-list-group'
                >
                  <View className='sub-title'>{v.chars}</View>
                  <View className='city-name-item'>
                    {v.list.map(city => {
                      return (
                        <View key={city.id} onClick={() => this.setCity(city.name)} className='city-name'>
                          {city.name}
                        </View>
                      )
                    })}
                  </View>
                </View>
              );
            })}
          </ScrollView>
          <View className='chars-list' onTouchMove={e => e.preventDefault()}>
            <View
              className='letter'
              onTouchStart={e => this.tapCharsStart(e)}
              onTouchMove={e => this.tapCharsMove(e)}
              onTouchEnd={e => this.tapCharsEnd(e)}
            >
              {cityList.map(v => {
                return (
                  <View
                    key={v.chars}
                    id={`city-${v.chars}`}
                    className={classnames(
                      'str',
                      `city-${v.chars}` === scrollId && 'curr'
                    )}
                  >
                    <View className={classnames('tips', charsTips && 'show')}>
                      {v.chars}
                    </View>
                    <View className='text'>{v.chars}</View>
                  </View>
                );
              })}
            </View>
          </View>
        </View>
      )
    )
  }
}
